package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"time"

	"bitbucket.org/ckrissun/goping"
)

// ip list file
// such as:
// ip-list.txt
// 127.0.0.1
var (
	confFile = flag.String("f", "", "ip list file")
	outFile  = flag.String("o", "", "output php file")
)

var (
	bestIP   string
	bestTime time.Duration
)

var (
	ipAddrs []*net.IPAddr
)

func main() {
	flag.Parse()
	if *confFile == "" || *outFile == "" {
		flag.PrintDefaults()
		return
	}

	b, err := ioutil.ReadFile(*confFile)
	if err != nil {
		log.Println("ReadIpList:", err)
		return
	}
	lines := bytes.Split(b, []byte("\n"))
	if len(lines) == 0 {
		log.Println("ReadIpList: empty ip list")
		return
	}

	// init ping routine
	for _, l := range lines {
		if len(l) == 0 {
			continue
		}
		addr, err := net.ResolveIPAddr("ip4:icmp", string(l))
		if err != nil {
			log.Println("invalid ip(%s), %v", l, err)
			return
		}
		ipAddrs = append(ipAddrs, addr)
	}

	scanAllIP()

	var ticker = time.NewTicker(2 * time.Minute)
	for {
		select {
		case <-ticker.C:
			scanAllIP()
		}
	}
	ticker.Stop()
}

func scanAllIP() {
	bestIP = ""
	bestTime = time.Hour

	for _, addr := range ipAddrs {
		rtt := goping.Ping(addr, 500*time.Millisecond)
		if rtt < 0 {
			continue
		}
		if rtt < bestTime {
			bestTime = rtt
			bestIP = addr.String()
		}
	}
	if len(bestIP) > 0 {
		writeBestIp(bestIP)
	}
}

const (
	fileTpt = `// ip-out.php
<?php
	$ip = "%s";
?>`
)

func writeBestIp(ip string) {
	err := ioutil.WriteFile(*outFile, []byte(fmt.Sprintf(fileTpt, ip)), 0644)
	if err != nil {
		log.Println("WriteFile:", err)
	}
}
